/*
 * @Description: 数据适配方法 Pro
 * @version:
 * @Author: E-CHOOSEUS R&D
 * @LastEditors: E-CHOOSEUS R&D
 */
import { cloneDeep } from 'lodash-unified'
import { nanoid } from 'nanoid'

import { parseToNum } from '@/utils/number'

import { getValFilledRow } from '../adapter'

// ? 重症护理单配置项分类
export const IcrDictType = {
  'yx-pgpf': 'yx-pgpf',
  'yx-gcx': 'yx-gcx',
  'yx-hlgc': 'yx-hlgc',
  'yx-yzzxjl': 'yx-yzzxjl',
  'yx-ysjl': 'yx-ysjl',
  'yx-bqgc': 'yx-bqgc',
  'yx-crl': 'yx-crl',
  'yx-hljl': 'yx-hljl',
  'yx-hlcz': 'yx-hlcz',
  date_value: 'date_value',
  operater: 'operater',
  'yx-crl-in': 'yx-crl-in', // ? 新增固定列 ”入量“
  'yx-crl-out': 'yx-crl-out', // ? 新增固定列 ”出量“
  unknown: 'unknown'
}

/**
 * @summary 测试状态: 已测试
 * @description 将护理单配置表头数据结构格式化, 简化预渲染模型
 * @param {*} cfgTitle 配置表头数据
 * @returns 返回数据结构统一的配置表头数据
 */
export function getPreRenderCfgTitle(cfgTitle) {
  const titleColumns = [] // 表头树列表

  for (let i = 0, iLen = cfgTitle.length; i < iLen; i++) {
    const l1Node = cfgTitle[i]

    const l1NodeChildList = []
    let l1NodeWidth = l1Node.titieWidth

    // TODO 该句违反了函数单一职责原则, 后续需要移除
    // l1Node.dictValue === "date_value" && (this.totalRows = parseToNum(l1Node.recordNum, 0)); // 总行数
    // l1Node.dictValue === IcrDictType.date_value && (iColumn._minWidth = 110); // * 给予时间日期列最小宽度值
    // l1Node.dictValue === IcrDictType["yx-hljl"] && (iColumn._minWidth = 250); // * 给予护理记录最小宽度
    // l1Node.dictValue === IcrDictType["yx-crl-in"] && (iColumn._minWidth = 160); // * 给予 "入量" 最小宽度
    // l1Node.dictValue === IcrDictType["yx-crl-out"] && (iColumn._minWidth = 100); // * 给予 "出量" 最小宽度

    const childNode = l1Node.childNode
    if (childNode && childNode.length > 0) {
      l1NodeWidth = 0
      for (let j = 0, jLen = childNode.length; j < jLen; j++) {
        const l2Node = childNode[j]
        const l2NodeChildList = []
        let l2NodeWidth = l2Node.titieWidth

        // // ? 特殊处理观察项结构体类型
        // if (l1Node.dictValue === IcrDictType["yx-gcx"] && l2Node.obsvDataType === "struct") {
        if (l2Node.childNode && l2Node.childNode.length > 0) {
          const jgtChild = l2Node.childNode || [] // 结构体类型观察项集合
          l2NodeWidth = 0
          for (let k = 0, kLen = jgtChild.length; k < kLen; k++) {
            const l3Node = jgtChild[k]
            const kColumn = {
              _uuid: l3Node._uuid,
              title: l3Node.title,
              propUnit: l3Node.propUnit,
              weights: l3Node.weights || 0, // 权重字段缺失
              dataType: l3Node.dataType, // ? 数据类型, 仅观察项类型有此值
              titleType: l3Node.titleType,
              titieWidth: l3Node.titieWidth,
              // _minWidth: 40, // 最小宽度
              _minWidth: 0, // 最小宽度
              childList: []
            }

            // l2NodeWidth += l3Node.titieWidth;
            l2NodeChildList.push(kColumn)
          }
        }

        const jColumn = {
          _uuid: l2Node._uuid,
          title: l2Node.title,
          propUnit: l2Node.propUnit,
          weights: l2Node.weights,
          dictValue: l2Node.dictValue,
          titieWidth: l2NodeWidth,
          _minWidth: 0, // 最小宽度
          dataType: l2Node.obsvDataType, // ? 数据类型, 仅观察项类型有此值
          titleType: l2Node.titleType,
          childList: l2NodeChildList
        }

        // l1NodeWidth += l2NodeWidth;
        l1NodeChildList.push(jColumn)
      }
    }
    const iColumn = {
      _uuid: l1Node._uuid,
      title: l1Node.title,
      propUnit: l1Node.propUnit,
      weights: l1Node.weights, // ! 该参数可能为 null
      dictValue: l1Node.dictValue,
      titieWidth: l1NodeWidth,
      titleType: l1Node.titleType,
      _minWidth: 0, // 最小宽度
      childList: l1NodeChildList
    }

    titleColumns.push(iColumn)
  }

  return titleColumns
}

/**
 * @description * 给表头数据设置 uuid, 并获取表格渲染一些重要参数
 * @param {*} tree
 * @param {*} otherInfo
 * @returns
 */
export function setCfgTitleSymbolAndGetKeyInfo(
  tree,
  otherInfo = { docHeadSelector: '', docFootSelector: '' }
) {
  const treeColumnMap = new Map() // 全量表头节点 map
  const leafColumnsMap = new Map() // 全部表头叶子节点 map
  let totalRows = 0 // 数据总行数

  let docHeadHeight = 0 // 文书头部（文书名称及基本信息）高度
  let docFootHeight = 0 // 文书底部（备注）高度
  // TODO 表头高度不应该在此处获取
  // ! 该高度在此处不可得
  const docTableHeadHeight = 0 // 表头高度

  //   TODO 测试是否存在渲染滞后的问题
  // * 获取文书头部高度
  try {
    const docHeaderDom = document.querySelector(otherInfo.docHeadSelector)
    const docFooterDom = document.querySelector(otherInfo.docFootSelector)
    docHeaderDom && (docHeadHeight = docHeaderDom.offsetHeight)
    docFooterDom && (docFootHeight = docFooterDom.offsetHeight)
  } catch (err) {
    // eslint-disable-next-line no-console
    console.error(
      'document.querySelector ',
      otherInfo.docHeadSelector,
      '  err: ',
      err
    )
  }

  /**
   * @description 这一个循环里, 做了三件事
   * * 第一件: 表头节点生成 uuid, 子节点存储父节点 uuid
   * * 第二件: 表头节点全量存放到 map, 叶子节点存放到 叶子map
   * * 第三件: 确定数据需要渲染的总行数, 并确定表头拆分时需要重复展示的项
   */
  for (let i = 0, Len = tree.length; i < Len; ++i) {
    const l1Node = tree[i]
    l1Node._uuid = nanoid()
    l1Node._pUuid = null // 存储父节点uuid
    treeColumnMap.set(l1Node._uuid, l1Node)
    const l1ChildList = l1Node.childNode || []

    if (!l1ChildList.length) {
      l1Node._isLeaf = true
      l1Node._dTreeMaxW = 0 // 纵深树的最大宽度
      leafColumnsMap.set(l1Node._uuid, l1Node) // 存储叶子节点
    }

    // ? 日期类型, 标明重复项
    if (l1Node.dictValue === IcrDictType.date_value) {
      l1Node._repeat = true
      totalRows = parseToNum(l1Node.recordNum, 0) // * 日期类型包含行数
    }

    for (let j = 0, jLen = l1ChildList.length; j < jLen; ++j) {
      const l2Node = l1ChildList[j]
      l2Node._uuid = nanoid()
      l2Node._pUuid = l1Node._uuid // 存储父节点uuid

      treeColumnMap.set(l2Node._uuid, l2Node)

      // // * 观察项, 且同时是结构体类型
      // if (l2Node.dictValue === IcrDictType["yx-gcx"] && l2Node.obsvDataType === "struct") {
      if (l2Node.childNode && l2Node.childNode.length > 0) {
        const jgtChild = l2Node.childNode || [] // 结构体类型观察项集合

        // // ? 特殊处理观察项结构体类型
        for (let k = 0, kLen = jgtChild.length; k < kLen; k++) {
          const jgtNode = jgtChild[k]
          jgtNode._uuid = nanoid()
          jgtNode._pUuid = l2Node._uuid // 存储父节点uuid

          treeColumnMap.set(jgtNode._uuid, jgtNode)

          jgtNode._isLeaf = true
          jgtNode._dTreeMaxW = 0 // 纵深树的最大宽度
          leafColumnsMap.set(jgtNode._uuid, jgtNode)
        }
      } else {
        l2Node._isLeaf = true
        l2Node._dTreeMaxW = 0 // 纵深树的最大宽度
        leafColumnsMap.set(l2Node._uuid, l2Node)
      }
    }
  }

  return {
    docHeadHeight: docHeadHeight, // 文书头部高度
    docFootHeight: docFootHeight, // 文书底部高度
    theadHeigh: docTableHeadHeight, // 表头高度
    totalDataRows: totalRows, // 总行数
    treeColumnMap: treeColumnMap, // 全量表头节点 map
    leafMap: leafColumnsMap // 全部表头叶子节点 map
  }
}

/**
 * @description 通过数据行模板, 目标行数和数据值列表, 获取渲染行数据
 * @param {*} totalRows 目标行数
 * @param {*} rowTemp 行模板
 * @param {*} fList 扁平化处理过后数据值列表
 * @returns
 */
export function resolveDataRowsAndValue(
  totalRows,
  rowTemp,
  fList,
  pagesInfo = []
) {
  // console.log("resolveDataRowsAndValue () totalRows, rowTemp, fList: ", rowTemp);
  const renderRowList = [] // * 渲染的表格行列表
  const pageOneWidth = pagesInfo[0] ? pagesInfo[0].pageXWidth : 0

  // * totalRows未设置或为0时
  if (!totalRows) {
    return renderRowList
  }

  /**
   * @description 获取数据行模板
   * @param {*} rawTemp 原表头相关行模板
   * @param {*} rowData 行（值）数据
   * @returns
   */
  const getRowTemp = (rawTemp, rowData) => {
    if (rowData.cType === 0) {
      return cloneDeep(rawTemp)
    }
    if (rowData.cType === 1) {
      //   timestamp: any;
      // t: any;
      // data: any[];
      // cType: number;
      // username: string;
      const summRowTemp = []
      let repeatWidth = 0
      for (const rItem of rawTemp) {
        // * 日期时间类型直接推入
        if (rItem.dictValue === IcrDictType.date_value) {
          summRowTemp.push(cloneDeep(rItem))
          if (repeatWidth == 0) {
            repeatWidth += rItem.width
          }
        }
        // * 操作人类型直接推入
        // if (rItem.dictValue === IcrDictType.operater) {
        //   summRowTemp.push(cloneDeep(rItem))
        // }
      }

      const item = {
        _uuid: null, // 指向的配置列 uuid
        dictValue: IcrDictType.unknown, // 保留所属分类标识, 未知的类型
        val: '', // 展示的值
        width: pageOneWidth ? pageOneWidth - repeatWidth : 'unset', // 宽度同头部配置列 _width
        _noHead: true, // 无头部数据项
        _paddingW: repeatWidth // 行内边距
      }
      summRowTemp.push(item)

      // * 推入operater
      // const operaterTemp = rawTemp.find(item => item.dictValue === IcrDictType.operater);
      // if (operaterTemp) {
      //   summRowTemp.push({
      //     ...operaterTemp,
      //   });
      // }

      return summRowTemp
    }
  }
  for (let i = 0, len = fList.length; i < len; ++i) {
    const nItem = fList[i]

    const fillTemp = getRowTemp(rowTemp, nItem)
    // * 表格行模板需要拷贝传入
    const renderRowItem = {
      height: 'unset',
      rData: getValFilledRow(fillTemp, nItem),
      rowType: nItem.cType
    }
    const leastOneNotEmpty = renderRowItem.rData.some(item => {
      if (item.dictValue == 'date_value' || item.dictValue == 'operater') {
        // if (item.dictValue == 'date_value') {
        return false
      }
      return item.val !== ''
    })
    if (leastOneNotEmpty) {
      renderRowList.push(renderRowItem)
    }

    // * 当数据列表长度大于 totalRows 时, 提前退出
    if (totalRows <= len && i + 1 === totalRows) {
      break
    }
  }

  // ! 根据产品要求,  不补全空行以填充行数
  /* // * 当数据长度小于要求 totalRows 时
  if (totalRows > fList.length) {
    // ? 行数不足时, 在这里补充
    while (renderRowList.length < totalRows) {
      // * 表格行模板需要拷贝传入
      const renderRowItem = { height: "unset", rData: getValFilledRow(cloneDeep(rowTemp), {}), rowType: 0 };
      renderRowList.push(renderRowItem);
    }
  } */

  return renderRowList
}
